package alpha.com.google.code.mechanic.janitor.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * The class is to compress files under a specified directory to a zip file.
 *
 * @Last_edited: Oct 29, 2014 
 *
 * @author jingjiejiang
 * @since Oct 28, 2014
 */
public class ZipFiles {

  private List<String> fileList;
  private String srcFilePath;
  private String dstnFile;
  
  public ZipFiles(String srcFilePath, String dstnFile) {
    
    fileList = new ArrayList<String>();
    this.srcFilePath = srcFilePath;
    this.dstnFile = dstnFile;
  }
  
  /**
   * The method is to traverse a directory and get all files under the directory.
   *
   * @param file The directory that is specified by users.
   */
  private void initFileList (File file) {
    
    if (file.isFile()) {
      fileList.add(initZipEntry(file.getAbsoluteFile().toString()));
    }
    
    if (file.isDirectory()) {
      String[] nodes = file.list();
      for (String filename: nodes) {
        initFileList(new File(file, filename));
      }
    }
  }
  
  /**
   * The method is to get the file name from the "file" path.
   *
   * @param file A file path. 
   * @return The file name.
   */
  private String initZipEntry (String file) {
    return file.substring(srcFilePath.length() + 1, file.length());
  }
  
  /**
   * The method is to zip the selected files under the directory "srcFilePath" 
   * to the path "dstnFilePath".
   *
   */
  public void zipFiles() {
    
    byte[] buffer = new byte[1024];
    initFileList(new File(srcFilePath));
    
    try {
      
      FileOutputStream fileout = new FileOutputStream(dstnFile);
      ZipOutputStream zipout = new ZipOutputStream(fileout);
      
      for (String file: this.fileList) {
        
        ZipEntry entry = new ZipEntry(file);
        zipout.putNextEntry(entry);
        
        FileInputStream filein = new FileInputStream(srcFilePath
            + File.separator + file);
        
        int length = 0;
        while ((length = filein.read(buffer)) > 0) {
          zipout.write(buffer, 0, length);  
        }
        
        filein.close();
      }
      
      zipout.closeEntry();
      zipout.close();
    } catch (IOException e) {
      Shell pshell = Display.getCurrent().getActiveShell();
      MessageDialog.openError(pshell, "Couldn't compress the "
          + "Context files", e.getMessage());
    }
  }
}
